package com.ledi.guns.modular.ledipay.controller;

import io.swagger.annotations.Api;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.plugins.Page;
import com.ledi.guns.common.annotion.Permission;
import com.ledi.guns.common.exception.BizExceptionEnum;
import com.ledi.guns.common.exception.BussinessException;
import com.ledi.guns.common.persistence.dao.BillDetailMapper;
import com.ledi.guns.common.persistence.model.Bill;
import com.ledi.guns.common.persistence.model.vo.BillClassSchoolItemVo;
import com.ledi.guns.common.persistence.model.vo.BillVo;
import com.ledi.guns.common.persistence.model.vo.CountTotal;
import com.ledi.guns.common.persistence.model.vo.OnlineVo;
import com.ledi.guns.common.persistence.model.vo.UserVo;
import com.ledi.guns.core.base.controller.BaseController;
import com.ledi.guns.core.base.tips.SuccessTip;
import com.ledi.guns.core.base.tips.Tip;
import com.ledi.guns.core.util.SystemConstans;
import com.ledi.guns.modular.ledipay.controller.req.bill.AddSchoolUser;
import com.ledi.guns.modular.ledipay.controller.req.bill.DownloadExcel;
import com.ledi.guns.modular.ledipay.controller.req.bill.Face2FaceBill;
import com.ledi.guns.modular.ledipay.controller.req.bill.FaceQueryBillInfo;
import com.ledi.guns.modular.ledipay.controller.req.bill.ImportBillDetaile;
import com.ledi.guns.modular.ledipay.controller.req.bill.ImportBillDetaileFile;
import com.ledi.guns.modular.ledipay.controller.req.bill.OfflinePayment;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryBillDetaile;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryBillInfo;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryCountTotal;
import com.ledi.guns.modular.ledipay.controller.req.bill.QueryUserInfo;
import com.ledi.guns.modular.ledipay.controller.req.clazz.ClassAdd.Add;
import com.ledi.guns.modular.ledipay.controller.req.clazz.ClassAdd.Update;
import com.ledi.guns.modular.ledipay.service.IBillService;
import com.ledi.guns.modular.ledipay.service.impl.EduPayCenter;

/**
 * 账单控制器
 *
 * @author fengshuonan
 * @Date 2017-11-29 11:02:55
 */
@Api
@RestController
@RequestMapping("/bill")
@Validated
public class BillController extends BaseController {

	@Autowired
	private IBillService billService;
	@Autowired
	private EduPayCenter eduPayCenter;
	@Autowired
	private BillDetailMapper billDetailMapper;

	/**
	 * @api {GET} /bill/download/template 下载模板
	 * @apiGroup bill
	 * @apiName excelTemplate
	 * @apiParam name 下载模板名称
	 * @apiParam reName 设置下载后的名称（可选）
	 * @apiError code 返回编码
	 * @apiError message 返回说明
	 * @apiSuccessExample {json} error-Response:
	 *                    {
	 *                    "code": 500,
	 *                    "message": "下载失败"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/download/template", method = RequestMethod.GET)
	public void excelTemplate(
			HttpServletRequest request, HttpServletResponse response) {

		DownloadExcel downloadExcel = new DownloadExcel();
		String name = request.getParameter("name");
		System.out.println(name);
		String reName = request.getParameter("reName");
		downloadExcel.setName(name);
		downloadExcel.setReName(reName);
		InputStream is = null;
		OutputStream os = null;
		try {
			downloadExcel.setName(downloadExcel.getName() + ".xls");
			String path = "/static/download/excel/" + downloadExcel.getName();

			if (downloadExcel.getReName() == null || "".equals(downloadExcel.getReName())) {
				downloadExcel.setReName(downloadExcel.getName());
			}
			downloadExcel.setReName(URLEncoder.encode(downloadExcel.getReName(), "UTF-8"));
			// 导出excel
			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition", "attachment;fileName=" + downloadExcel.getReName());

			is = new FileInputStream(request.getServletContext().getRealPath(path));
			os = response.getOutputStream();
			byte[] b = new byte[512];
			int length;
			while ((length = is.read(b)) > 0) {
				os.write(b, 0, length);
			}
		} catch (Exception e) {
			throw new BussinessException(BizExceptionEnum.DOWNLOAD_EXCEL_ERROR);
		} finally {
			try {
				if (is != null) {
					is.close();
				}
				if (os != null) {
					os.flush();
					os.close();
				}
			} catch (IOException e) {
				throw new BussinessException(BizExceptionEnum.DOWNLOAD_EXCEL_ERROR);
			}
		}
	}

	/**
	 * @api {POST} /bill/importBillDetaile 发送账单
	 * @apiGroup bill
	 * @apiName importBillDetaile
	 * @apiParam billName 账单名称
	 * @apiParam billEndTime 账单收费截止时间,格式"yyyy-MM-dd"
	 * @apiParam billDetaileUrl 上传账单后的URL,相对路径
	 * @apiSuccess id 账单ID
	 * @apiSuccess status 状态（0：全部成功，1：部分成功，2：全部失败）
	 * @apiSuccess msgNum 如果是部分成功和全部失败，失败的子账单数量
	 * @apiSuccess studentNum 导入数量
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "id": 62,
	 *                    "msgNum": 3,
	 *                    "status": 2,
	 *                    "studentNum": 3
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/importBillDetaile", method = RequestMethod.POST)
	@Permission
	public Tip importBillDetaile(@RequestBody @Valid ImportBillDetaile importBillDetaile) {

		ImportBillDetaileFile importBillDetaileFile = billService.newSendBillDetaile(importBillDetaile);
		eduPayCenter.setBillId(importBillDetaileFile.getId()).sendBill();

		return SuccessTip.buildSuccess(importBillDetaileFile);
	}

	/**
	 * @api {POST} /bill/billList 账单列表
	 * @apiGroup bill
	 * @apiName billList
	 * @apiParam billName 账单名称
	 * @apiParam billNumber 账单编号
	 * @apiParam startTime 起始日期
	 * @apiParam endTime 结束日期
	 * @apiParam sendStatus 发送状态（-1:发送中 0：发送成功，1：发送失败）
	 * @apiParam pageNo 页码（默认1）
	 * @apiParam pageSize 单页总和数（默认10条）
	 * @apiParam orderBy 排序字段（默认id）
	 * @apiParam orderType 排序规则，ASC：升序，DESC：降序（默认DESC）
	 * @apiSuccess id 账单编号
	 * @apiSuccess count 总数
	 * @apiSuccess name 账单名称
	 * @apiSuccess createTime 账单生成时间
	 * @apiSuccess billEndTime 账单截止时间
	 * @apiSuccess studentNum 应缴学生总数
	 * @apiSuccess studentNnumPay 实缴学生总数
	 * @apiSuccess total 应缴费用总和
	 * @apiSuccess totalPay 实缴费用总和
	 * @apiSuccess isSuccess 发送状态（-1：发送中，0：发送成功，1：发送部分失败，2：发送全部失败）
	 * @apiSuccess sendFileNum 发送失败时未发送成功的数量
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "count": 3,
	 *                    "firstResult": 0,
	 *                    "list": [
	 *                    {
	 *                    "billEndTime": "2017-12-01 00:00:00",
	 *                    "createTime": "2017-12-01 15:50:02",
	 *                    "id": "",
	 *                    "isSuccess": 1,
	 *                    "name": "围绕服务任务",
	 *                    "sendFileNum": 2,
	 *                    "studentNum": 1,
	 *                    "studentNumPay": 0,
	 *                    "total": 0.03,
	 *                    "totalPay": 0
	 *                    }
	 *                    ],
	 *                    "orderBy": "id",
	 *                    "orderType": "DESC",
	 *                    "pageNo": 1,
	 *                    "pageSize": 20,
	 *                    "search": {
	 *                    "billName": "围绕",
	 *                    "orderType": "DESC",
	 *                    "defaultPageSize": 10,
	 *                    "pageNo": 1,
	 *                    "pageSize": 20,
	 *                    "orderBy": "id",
	 *                    "firstResult": 0,
	 *                    "startTime": "",
	 *                    "sendStatus": "",
	 *                    "endTime": ""
	 *                    },
	 *                    "total": 3
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/billList", method = RequestMethod.POST)
	@Permission
	public Tip billList(@RequestBody QueryBillInfo queryBillInfo) {

		queryBillInfo.checkOrder(BillVo.class);
		Page<BillVo> page = billService.findBillList(new Page<BillVo>(queryBillInfo.getPageNo(), queryBillInfo.getPageSize()), queryBillInfo);
		return SuccessTip.buildSuccess(page);
	}

	/**
	 * @api {GET} /bill/downloadBillDetaile 下载账单明细
	 * @apiGroup bill
	 * @apiName downloadBillDetaile
	 * @apiParam {int} flag 是否导出全部0否1是
	 * @apiParam {int} billId 账单编号
	 * @apiParam {String } billDetailIds 账单明细Id(可以是多选的，中间用逗号分割)
	 * @apiParam sendStatus 发送状态（0：发送失败，1：未支付，2：已支付,3：账单关闭 ）
	 * @apiSuccess studentName 学生名字
	 * @apiSuccess className 学生班级
	 * @apiSuccess parentMobile 家长手机号
	 * @apiSuccess payWay 付款方式(ALIPAY:支付宝，WEIXIN:微信支付,CASHS:现金，GIRO:转账，OTHER:其他)
	 * @apiError {int} code 返回编码
	 * @apiError message 返回说明
	 * @apiSuccessExample {json} error-Response:
	 *                    {
	 *                    "code": 500,
	 *                    "message": "下载失败"
	 *                    }
	 * @apiVersion 1.3.0
	 */
	@RequestMapping(value = "/downloadBillDetaile", method = RequestMethod.GET)
	@Permission
	public void downloadBillDetaile(
			HttpServletRequest request, HttpServletResponse response) {

		billService.downloadBillDetaile(request, response);

	}

	/**
	 * @api {GET} /bill/getBillName 查询账单名称
	 * @apiGroup bill
	 * @apiName getBillName
	 * @apiSuccess id 账单ID
	 * @apiSuccess name 账单名称
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    "code": 200,
	 *                    "data": [
	 *                    {
	 *                    "id": 20,
	 *                    "name": "围绕服务任务"
	 *                    }
	 *                    ],
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/getBillName", method = RequestMethod.GET)
	@Permission
	public Tip getClassInfo() {

		List<Bill> bills = billService.getBillName();
		return SuccessTip.buildSuccess(bills);
	}

	/**
	 * @api {GET} /bill/getBillInfo/{id} 查询账单信息
	 * @apiGroup bill
	 * @apiName getBillInfo
	 * @apiParam {int} id 账单ID
	 * @apiSuccess {String} name 账单名称
	 * @apiSuccess {int} studentNum 应缴账单人数
	 * @apiSuccess {int} studentNumPay 实际缴费人数
	 * @apiSuccess {int} studentNumWeixinPay 微信缴费人数
	 * @apiSuccess {int} studentNumAliPay 支付宝缴费人数
	 * @apiSuccess {int} studentNumUndergroundPay 线下缴费人数
	 * @apiSuccess {int} total 应缴金额总数
	 * @apiSuccess {int} totalPay 实缴金额
	 * @apiSuccess {int} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "id": 53,
	 *                    "name": "测试账单-zdw",
	 *                    "studentNum": 2,
	 *                    "studentNumPay": 0,
	 *                    "total": 0.25,
	 *                    "totalPay": 0,
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.3.0
	 */
	@RequestMapping(value = "/getBillInfo/{id}", method = RequestMethod.GET)
	@Permission
	public Tip getBillInfo(@PathVariable(value = "id") Long id) {

		BillVo bills = billService.getBillInfo(id);
		return SuccessTip.buildSuccess(bills);
	}

	/**
	 * @api {POST} /bill/countTotal 统计收入
	 * @apiGroup bill
	 * @apiName countTotal
	 * @apiParam startTime 开始日期
	 * @apiParam endTime 结束日期
	 * @apiSuccess findTotal 应付金额
	 * @apiSuccess findTotalPay 实际金额
	 * @apiSuccess total 历史总额
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "findTotal": 198.72,
	 *                    "findTotalPay": 197.03,
	 *                    "total": 197.03
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/countTotal", method = RequestMethod.POST)
	@Permission
	public Tip countTotal(@RequestBody @Valid QueryCountTotal queryCountTotal) {

		CountTotal countTotal = billService.getCountTotal(queryCountTotal);
		return SuccessTip.buildSuccess(countTotal);
	}

	/**
	 * @api {POST} /bill/schoolUserList 学校成员列表
	 * @apiGroup bill
	 * @apiName schoolUserList
	 * @apiParam {String} type 平台类型（1，幼儿园，2代理商3，员工）
	 * @apiParam {String} pageNo 页码（默认1）
	 * @apiParam {String} pageSize 单页总和数（默认10条）
	 * @apiParam {String} orderBy 排序字段（默认id）
	 * @apiParam {String} account 账号
	 * @apiParam {String} name 用户名称
	 * @apiParam {String} roleType 0老师1管理员
	 * @apiParam {String} orderType 排序规则，ASC：升序，DESC：降序（默认DESC）
	 * @apiSuccess {int} id 用户ID
	 * @apiSuccess {int} count 总数
	 * @apiSuccess {String} name 用户名字
	 * @apiSuccess {String} phone 用户手机
	 * @apiSuccess {int} isBoss 是否创始人(1是，0否)
	 * @apiSuccess {String} alipayPid 阿里PID
	 * @apiSuccess {String} createtime 创建时间
	 * @apiSuccess {String} createName 创建人名字
	 * @apiSuccess {String} roleName 用户角色名称
	 * @apiSuccess {String} roleid 用户角色ID
	 * @apiSuccess {String} comment 备注
	 * @apiSuccess {String} className 带班名称
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "count": 1,
	 *                    "firstResult": 0,
	 *                    "list": [
	 *                    {
	 *                    "alipayPid": "2088821837534878",
	 *                    "comment": "",
	 *                    "createName": "",
	 *                    "createtime": "2016-01-29 08:49:53",
	 *                    "id": "1",
	 *                    "name": "张三",
	 *                    "phone": "18200000000",
	 *                    "roleName": "超级管理员",
	 *                    "roleid": "1"
	 *                    }
	 *                    ],
	 *                    "orderBy": "id",
	 *                    "orderType": "DESC",
	 *                    "pageNo": 1,
	 *                    "pageSize": 10,
	 *                    "search": {
	 *                    "orderType": "DESC",
	 *                    "defaultPageSize": 10,
	 *                    "pageNo": 1,
	 *                    "schoolId": 1,
	 *                    "pageSize": 10,
	 *                    "orderBy": "id",
	 *                    "firstResult": 0
	 *                    },
	 *                    "total": 1
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/schoolUserList", method = RequestMethod.POST)
	@Permission
	public Tip schoolUserList(@RequestBody @Valid QueryUserInfo queryUserInfo) {

		queryUserInfo.checkOrder(UserVo.class);
		queryUserInfo.setOrderBy("createtime");
		Page<UserVo> page = billService.findSchoolUserList(new Page<UserVo>(queryUserInfo.getPageNo(), queryUserInfo.getPageSize()), queryUserInfo);
		return SuccessTip.buildSuccess(page);
	}

	/**
	 * @api {POST} /bill/addSchoolUser 添加学校用户
	 * @apiGroup bill
	 * @apiName addSchoolUser
	 * @apiParam {String} name 用户名称
	 * @apiParam {String} phone 手机号
	 * @apiParam {String} pwd 密码
	 * @apiParam {int} type 用户类型（0老师，1园长）
	 * @apiParam {Array} classIds 代理班级
	 * @apiParam {String} comment 备注
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/addSchoolUser", method = RequestMethod.POST)
	@Permission
	public Tip addSchoolUser(@RequestBody @Validated(Add.class) AddSchoolUser addSchoolUser) {

		billService.addSchoolUser(addSchoolUser);
		return SuccessTip.buildSuccess();
	}

	/**
	 * @api {PUT} /bill/mergeSchoolUser 编辑学校用户
	 * @apiGroup bill
	 * @apiName mergeSchoolUser
	 * @apiParam {String} name 用户名称
	 * @apiParam {String} id ID
	 * @apiParam {Array} classIds 代理班级
	 * @apiParam {String} comment 备注
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/mergeSchoolUser", method = RequestMethod.PUT)
	@Permission
	public Tip mergeSchoolUser(@RequestBody @Validated(Update.class) AddSchoolUser addSchoolUser) {

		billService.mergeSchoolUser(addSchoolUser);
		return SuccessTip.buildSuccess();
	}

	/**
	 * @api {DELETE} /bill/deleteSchoolUser/{id} 删除学校用户
	 * @apiGroup bill
	 * @apiName deleteSchoolUser
	 * @apiParam id 用户id
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/deleteSchoolUser/{id}", method = RequestMethod.DELETE)
	@Permission
	public Tip deleteSchoolUser(@PathVariable Integer id) {

		billService.deleteSchoolUser(id);
		return SuccessTip.buildSuccess();
	}

	/**
	 * @api {GET} /bill/getSchoolUser 获取登录用户学校信息
	 * @apiGroup bill
	 * @apiName getSchoolUser
	 * @apiParam id 用户id
	 * @apiSuccess schoolName 学校名称
	 * @apiSuccess schoolNo 阿里学校标识
	 * @apiSuccess schoolProvinceName 学校省
	 * @apiSuccess schoolCityName 学校市
	 * @apiSuccess schoolDistrictName 学校区
	 * @apiSuccess schoolContactPeople 联系人
	 * @apiSuccess contactTel 联系人手机号
	 * @apiSuccess schoolSubMchId 学校微信商户号
	 * @apiSuccess schoolMailBox 学校对公邮箱
	 * @apiSuccess schoolAlipayNumber 学校支付宝对公账号
	 * @apiSuccess giveCount 赠送数目
	 * @apiSuccess freeMonth 免费月份
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "schoolName": "乐迪yuyu",
	 *                    "schoolNo": "10007"
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/getSchoolUser", method = RequestMethod.GET)
	@Permission
	public Tip getSchoolUser() {

		UserVo userVo = billService.getSchoolUser();
		return SuccessTip.buildSuccess(userVo);
	}

	/**
	 * @api {POST} /bill/offlinePayment 新增线下缴费
	 * @apiGroup bill
	 * @apiName offlinePayment
	 * @apiParam payWay 支付方式0现金支付，1网银转账2，其他
	 * @apiParam childName 幼儿名称
	 * @apiParam classId 班级id
	 * @apiParam total 付款总额
	 * @apiParam parentMobile 家长手机
	 * @apiParam comment 备注
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.3.0
	 */
	@RequestMapping(value = "/offlinePayment", method = RequestMethod.POST)
	@Permission
	public Tip offlinePayment(@RequestBody @Valid OfflinePayment offlinePayment) {

		billService.offlinePayment(offlinePayment);
		return SuccessTip.buildSuccess();
	}

	/**
	 * @api {POST} /bill/face2FaceBillList 当面付账单列表
	 * @apiGroup bill
	 * @apiName {String} face2FaceBillList
	 * @apiParam {int} pageNo 页码（默认1）
	 * @apiParam {int} pageSize 单页数（默认10条）
	 * @apiParam {String} orderBy 排序字段（默认id）
	 * @apiParam {String} orderType 排序规则，ASC：升序，DESC：降序（默认DESC）
	 * @apiSuccess {int} id 账单编号
	 * @apiSuccess {String} name 账单名称
	 * @apiSuccess {Date} createTime 账单生成时间
	 * @apiSuccess {Date} billEndTime 账单截止时间
	 * @apiSuccess {int} studentNnumPay 实缴学生总数
	 * @apiSuccess {String} totalPay 实缴费用总和
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "count": 3,
	 *                    "firstResult": 0,
	 *                    "list": [
	 *                    {
	 *                    "billEndTime": "2017-12-01 00:00:00",
	 *                    "createTime": "2017-12-01 15:50:02",
	 *                    "id": "",
	 *                    "isSuccess": 1,
	 *                    "name": "围绕服务任务",
	 *                    "sendFileNum": 2,
	 *                    "studentNum": 1,
	 *                    "studentNumPay": 0,
	 *                    "total": 0.03,
	 *                    "totalPay": 0
	 *                    }
	 *                    ],
	 *                    "orderBy": "id",
	 *                    "orderType": "DESC",
	 *                    "pageNo": 1,
	 *                    "pageSize": 20,
	 *                    "search": {
	 *                    "billName": "围绕",
	 *                    "orderType": "DESC",
	 *                    "defaultPageSize": 10,
	 *                    "pageNo": 1,
	 *                    "pageSize": 20,
	 *                    "orderBy": "id",
	 *                    "firstResult": 0,
	 *                    "startTime": "",
	 *                    "sendStatus": "",
	 *                    "endTime": ""
	 *                    },
	 *                    "total": 3
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/face2FaceBillList", method = RequestMethod.POST)
	@Permission
	public Tip face2FaceBillList(@RequestBody FaceQueryBillInfo queryBillInfo) {

		queryBillInfo.checkOrder(Bill.class);
		Page<Bill> page = billService.findFaceBillList(new Page<Bill>(queryBillInfo.getPageNo(), queryBillInfo.getPageSize()), queryBillInfo);
		return SuccessTip.buildSuccess(page);
	}

	/**
	 * @api {POST} /bill/createFaceBillDetaile 创建当面付账单
	 * @apiGroup bill
	 * @apiName createFaceBillDetaile
	 * @apiParam {String} billName 账单名称
	 * @apiParam {String} billEndTime 账单收费截止时间,格式"yyyy-MM-dd"
	 * @apiParam {Array} classIds 账单所属班级id
	 * @apiParam {Array} schoolPayItemIds 收费项目id
	 * @apiSuccess {String} id 账单ID
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiParamExample {json} Request-Example:
	 *                  {
	 *                  "billEndTime": "2018-08-22T08:58:29.711Z",
	 *                  "billName": "账单名称",
	 *                  "classIds": [1169
	 *                  ],
	 *                  "schoolPayItemIds": [5
	 *                  ]
	 *                  }
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": 228,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/createFaceBillDetaile", method = RequestMethod.POST)
	@Permission
	public Tip createFaceBillDetaile(@RequestBody @Validated(Add.class) Face2FaceBill face2FaceBill) {

		Long billId = billService.createFaceBillDetaile(face2FaceBill, SystemConstans.TWO);
		return SuccessTip.buildSuccess(billId);
	}

	/**
	 * @api {POST} /bill/createOnlineBillDetaile 创建在线账单
	 * @apiGroup bill
	 * @apiName createOnlineBillDetaile
	 * @apiParam {String} billName 账单名称
	 * @apiParam {String} billEndTime 账单收费截止时间,格式"yyyy-MM-dd"
	 * @apiParam {Array} classIds 账单所属班级id
	 * @apiParam {Array} schoolPayItemIds 收费项目id
	 * @apiSuccess {String} id 账单ID
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiParamExample {json} Request-Example:
	 *                  {
	 *                  "billEndTime": "2018-08-22T08:58:29.711Z",
	 *                  "billName": "账单名称",
	 *                  "classIds": [1169
	 *                  ],
	 *                  "schoolPayItemIds": [5
	 *                  ]
	 *                  }
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": 228,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/createOnlineBillDetaile", method = RequestMethod.POST)
	@Permission
	public Tip createOnlineBillDetaile(@RequestBody @Validated(Add.class) Face2FaceBill face2FaceBill) {

		Long billId = billService.createFaceBillDetaile(face2FaceBill, SystemConstans.YES);
		return SuccessTip.buildSuccess(billId);
	}

	/**
	 * @api {POST} /bill/updateFaceBillDetaile 账单新增班级
	 * @apiGroup bill
	 * @apiName updateFaceBillDetaile
	 * @apiParam {int} id 账单ID
	 * @apiParam {Array} classIds 账单所属班级id
	 * @apiSuccess {String} id 账单ID
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiParamExample {json} Request-Example:
	 *                  {
	 *                  "id": 1,
	 *                  "classIds": [1169
	 *                  ]
	 *                  }
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": 228,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/updateFaceBillDetaile", method = RequestMethod.POST)
	@Permission
	public Tip updateFaceBillDetaile(@RequestBody @Validated(Update.class) Face2FaceBill face2FaceBill) {

		Long billId = billService.createFaceBillDetaile(face2FaceBill, SystemConstans.YES);
		return SuccessTip.buildSuccess(billId);
	}

	/**
	 * @api {GET} /bill/billClassSchoolItemList/{billId} 预生成账单班级收费项列表
	 * @apiGroup bill
	 * @apiName billClassSchoolItemList
	 * @apiParam billId 账单id
	 * @apiSuccess id 账单编号
	 * @apiSuccess gradeId 年级Id
	 * @apiSuccess gradeName 年级名称
	 * @apiSuccess classId 班级id
	 * @apiSuccess className 班级名称
	 * @apiSuccess items 缴费项
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "tableSet": [
	 *                    [
	 *                    240,
	 *                    111,
	 *                    124.12,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111.55,
	 *                    1157,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111,
	 *                    "12312",
	 *                    231.15,
	 *                    222,
	 *                    29,
	 *                    111,
	 *                    0,
	 *                    100
	 *                    ],
	 *                    [
	 *                    240,
	 *                    111,
	 *                    124.12,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111.55,
	 *                    1170,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111,
	 *                    "123",
	 *                    231.15,
	 *                    222,
	 *                    28,
	 *                    111,
	 *                    0,
	 *                    100
	 *                    ],
	 *                    [
	 *                    240,
	 *                    111,
	 *                    124.12,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111.55,
	 *                    1171,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111,
	 *                    "1111",
	 *                    231.15,
	 *                    222,
	 *                    26,
	 *                    111,
	 *                    0,
	 *                    100
	 *                    ],
	 *                    [
	 *                    240,
	 *                    111,
	 *                    124.12,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111.55,
	 *                    1174,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    0,
	 *                    111,
	 *                    "gg",
	 *                    231.15,
	 *                    222,
	 *                    27,
	 *                    111,
	 *                    0,
	 *                    100
	 *                    ]
	 *                    ],
	 *                    "titleSet": [
	 *                    "bill_id",
	 *                    "书本费",
	 *                    "王者荣耀高分段",
	 *                    "xuzong",
	 *                    "打车费",
	 *                    "33 退款",
	 *                    "11 必交",
	 *                    "徐总上厕所了",
	 *                    "classId",
	 *                    "杂费123",
	 *                    "123",
	 *                    "sdf",
	 *                    "22 选交 必交",
	 *                    "幼儿班画画课程",
	 *                    "name",
	 *                    "徐总撩妹课程",
	 *                    "书法绘画",
	 *                    "id",
	 *                    "幼儿班跳舞",
	 *                    "酱油费",
	 *                    "2018春季学费"
	 *                    ]
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.1.0
	 */
	@RequestMapping(value = "/billClassSchoolItemList/{billId}", method = RequestMethod.GET)
	@Permission
	public Tip billClassSchoolItemList(@PathVariable Long billId) {

		OnlineVo page = billService.billClassSchoolItemList(billId);
		return SuccessTip.buildSuccess(page);
	}

	/**
	 * @api {GET} /bill/removeClassBillItem/{id} 删除缴费班级
	 * @apiGroup bill
	 * @apiName removeClassBillItem
	 * @apiParam id 缴费班级关系id
	 * @apiSuccess code 返回编码（200成功）
	 * @apiSuccess message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/removeClassBillItem/{id}", method = RequestMethod.GET)
	@Permission
	public Tip removeClassBillItem(@PathVariable("id") Long id) {

		billService.removeClassBillItem(id);
		return SuccessTip.buildSuccess();
	}

	/**
	 * @api {POST} /bill/createBillDetill 创建未发送账单明细
	 * @apiGroup bill
	 * @apiName createBillDetill
	 * @apiParam {Array} billClassIds 缴费班级关系id
	 * @apiParam {String} billName 缴费账单名称
	 * @apiParam {Date} billEndTime 缴费截止时间
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/createBillDetill", method = RequestMethod.POST)
	@Permission
	public Tip createBillDetill(@RequestBody @Valid QueryBillDetaile queryBillDetaile) {

		Long billId = billService.createBillDetill(queryBillDetaile);
		return SuccessTip.buildSuccess(billId);
	}

	/**
	 * @api {GET} /bill/sendOnlineBill/{billId} 发送在线创建的账单
	 * @apiGroup bill
	 * @apiName sendOnlineBill
	 * @apiParam {Long} billId 账单id
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/sendOnlineBill/{billId}", method = RequestMethod.GET)
	@Permission
	public Tip sendOnlineBill(@PathVariable("billId") Long billId) {

		eduPayCenter.setBillId(billId).sendBill();
		return SuccessTip.buildSuccess(billId);
	}

	/**
	 * @api {GET} /bill/getBillClassSchoolItem/{billId} 账单班级收费项详情
	 * @apiGroup bill
	 * @apiName sendOnlineBill
	 * @apiParam {Long} billId 账单id
	 * @apiSuccess {Long} billId 账单id
	 * @apiSuccess {String} billName 账单名称
	 * @apiSuccess {String} billEndTime 账单截止时间
	 * @apiSuccess {Array} ...classIds 所选班级Id集合
	 * @apiSuccess {Array} ...payItems 收费项
	 * @apiSuccess {String} code 返回编码（200成功）
	 * @apiSuccess {String} message 返回说明
	 * @apiSuccessExample {json} Success-Response:
	 *                    {
	 *                    "code": 200,
	 *                    "data": {
	 *                    "billId": 557,
	 *                    "billName": "新开学账单",
	 *                    "classIds": [
	 *                    392,
	 *                    388
	 *                    ],
	 *                    "payItems": [
	 *                    {
	 *                    "createTime": "2018-08-24 09:47:40",
	 *                    "creatorId": 106,
	 *                    "creatorRole": "6",
	 *                    "flag": 1,
	 *                    "id": 11,
	 *                    "isDelete": 0,
	 *                    "money": 180,
	 *                    "name": "校服费",
	 *                    "remark": "一年级",
	 *                    "schoolId": 29,
	 *                    "updateTime": "",
	 *                    "updaterId": "",
	 *                    "updaterRole": "",
	 *                    "versionNo": 0
	 *                    },
	 *                    {
	 *                    "createTime": "2018-08-24 09:48:12",
	 *                    "creatorId": 106,
	 *                    "creatorRole": "6",
	 *                    "flag": 0,
	 *                    "id": 12,
	 *                    "isDelete": 0,
	 *                    "money": 500,
	 *                    "name": "杂费111",
	 *                    "remark": "一年级",
	 *                    "schoolId": 29,
	 *                    "updateTime": "",
	 *                    "updaterId": "",
	 *                    "updaterRole": "",
	 *                    "versionNo": 0
	 *                    },
	 *                    {
	 *                    "createTime": "2018-08-24 09:48:32",
	 *                    "creatorId": 106,
	 *                    "creatorRole": "6",
	 *                    "flag": 2,
	 *                    "id": 13,
	 *                    "isDelete": 0,
	 *                    "money": 12,
	 *                    "name": "退费",
	 *                    "remark": "一年级",
	 *                    "schoolId": 29,
	 *                    "updateTime": "2018-08-31 14:41:49",
	 *                    "updaterId": 87,
	 *                    "updaterRole": "6,9",
	 *                    "versionNo": 1
	 *                    }
	 *                    ]
	 *                    },
	 *                    "message": "成功"
	 *                    }
	 * @apiVersion 1.4.0
	 */
	@RequestMapping(value = "/getBillClassSchoolItem/{billId}", method = RequestMethod.GET)
	// @Permission
	public Tip getBillClassSchoolItem(@PathVariable("billId") Long billId) {

		BillClassSchoolItemVo bo = billService.getBillClassSchoolItem(billId);
		return SuccessTip.buildSuccess(bo);
	}

}
